package org.dftproject.pgv.core;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.dftproject.gedcom.core.IGedcom;
import org.dftproject.gedcom.core.GedcomPerson;
import org.dftproject.genesis.core.collections.Collection;
import org.dftproject.genesis.core.collections.CollectionManager;
import org.dftproject.genesis.core.data.flow.Collector;
import org.dftproject.genesis.core.data.flow.DataProvider;
import org.dftproject.genesis.data.genealogy.IPerson;
import org.dftproject.pgv.core.racp.PGVGedcom;
import org.dftproject.pgv.core.racp.Session;
import org.dftproject.pgv.core.racp.SessionManager;

public class PGVDataProvider extends DataProvider {
	
	public final static String ID = PGVDataProvider.class.getName();
	
	private final static Pattern httpPattern = Pattern.compile("^(https?://.*?/)individual.php\\?(.*?)(#.*)?$");
	private final static Pattern queryStringPattern = Pattern.compile("([^=&]+)=([^&]+)&");

	@Override
	public void getRelatedObjects(final String uri, final Collector<Object> collector) {
		try {
			collector.setProviderStatus(ID, true);
			
			// Have we been canceled since this job was scheduled?
			
			if (collector.isCanceled())
				return;

			// Is this an "http" URL?
				
			Matcher matcher = httpPattern.matcher(uri);
			if (matcher.matches()) {
				// Get the parts of the URL
				
				String url = matcher.group(1);
				String gedcomId = null;
				String xref = null;
				
				String queryString = matcher.group(2);
				if (!queryString.endsWith("&"))
					queryString += "&";
				matcher = queryStringPattern.matcher(queryString);
				while (matcher.find()) {
					if ("ged".equalsIgnoreCase(matcher.group(1)) || "gedcom".equalsIgnoreCase(matcher.group(1)))
						gedcomId = matcher.group(2);
					if ("pid".equalsIgnoreCase(matcher.group(1)))
						xref = matcher.group(2);
				}
				
				if (xref != null) {
					Session session = getSession(url);
					IGedcom gedcom = new PGVGedcom(session, gedcomId);
					IPerson person = gedcom.getPerson(xref);
					if (person != null)
						collector.addElement(person);
				}
			}
		} finally {
			collector.setProviderStatus(ID, false);
		}
	}

	@Override
	public void getRelatedObjects(IPerson person, Collector<Object> collector) {
		try {
			collector.setProviderStatus(ID, true);
			
			// Have we been canceled since this job was scheduled?
			
			if (collector.isCanceled())
				return;

			if (person instanceof GedcomPerson) {
				GedcomPerson gedcomPerson = (GedcomPerson) person;
				IGedcom gedcom = gedcomPerson.getGedcom();
				if (gedcom instanceof PGVGedcom) {
					PGVGedcom pgvPGVGedcom = (PGVGedcom) gedcom;
					
					try {					
						collector.addElement(new URL(pgvPGVGedcom.getUrl() + "individual.php?pid=" + gedcomPerson.getId() + "&GEDCOM=" + pgvPGVGedcom.getGedcomId()));
					} catch (MalformedURLException e) {
						// TODO Auto-generated catch block
						e.printStackTrace(System.err);
					}
				}
			}
		} finally {
			collector.setProviderStatus(ID, false);
		}
	}
	
	public static Session getSession(String url) {
		for (Collection collection : CollectionManager.getDefault().getCollections("org.dftproject.pgv")) {
			Properties props = new Properties();
			try {
				props.load(new ByteArrayInputStream(collection.getData().getBytes()));
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			if (url.equals(props.getProperty("url")))
				return SessionManager.getDefault().getSession(props.getProperty("url"), props.getProperty("username"), props.getProperty("password"));
		}
		
		return SessionManager.getDefault().getSession(url);
	}

}
